作者:Justin( j_q_king@foxmail.com

起笔: 2024-04-08 Mon 20:10 | 凝墨: 2024-08-01 Thu 08:10

将 Windows 截图插入 WSL 中的 Emacs org 中显示*

今天花费了一下午写了一个 20 行的小功能,但很有意义就当是,简要说说,也许放在博客对别人有帮助。

起因是用它写关于准晶的文章,然后显然科普文需要一些图片点缀,就想着能不能通过 Windows 截图,然后一键贴到 Org 里面,毕竟它这么强大。于是历经 org-download 、受别人启发、原始版、 ChatGPT 优化版得到最后比较简单的函数

不想看下面是代码:

环境:WSL 中的 Emacs

依赖 Windows 截图后剪切板中的图片,使用联想小新 win11 无问题

(defun paste-file-from-win-clip-to-org ()
  "Insert link of WINDOWS clip to current org file."
  (interactive)
  (let* ((org-path (substring buffer-file-name 0 -4))
         (org-dir (file-name-directory org-path))
	 (org-name (file-name-nondirectory org-path))
         (file-name (format-time-string "%Y%m%d%H%M%S.png"))
         (file-dir (concat org-dir org-name))
	 (file-path (expand-file-name file-name file-dir)))
    (unless (file-directory-p file-dir)
      (make-directory file-dir t))
    (call-process-shell-command (concat "powershell.exe -Command \"(Get-Clipboard -Format image).Save('$(wslpath -w " file-path ")')\" "))
    (message (concat "\norg-path: " org-path "\norg-dir: " org-dir "\norg-name: " org-name "\n file-name: " file-name "\n file-dir: " file-dir "\n file-path: " file-path))
    (if (file-exists-p file-path)
        (progn
          (insert (format "[[file:%s]]" (concat org-name "/" file-name)))
          (org-display-inline-images))
      (message "Failed, file does not exist."))))

(global-set-key (kbd "C-c v") 'paste-file-from-win-clip-to-org)

于是得到

  --- yourFileName.org <-+
  |                      *
  --- yourFileName       * 
  |   |                  *
  |   --- screenshot.png +

简单流程就是

  1. 截图
  2. 获得当前 buffer 名称(文件地址),切掉 .org 后缀名
  3. 创建和 Org 同名的子目录(有了就跳过)
  4. 调用 Windows PowerShell 通过 GetClipboard 指令将剪切板上的截图保存到 2. 中文件夹
  5. 在当前位置 insert 链接并且显示图片

先使用 org-download 不过在有的时候粘贴报错

  At the beginning of line ...

而且我基本用不到这个插件功能,本着能少一事少一事的态度(心里默念:可以更快打开,防止暗中插件占用快捷键,占用空间…),所需的功能就是一个转移插入,干脆自己做一个。

其实,最关键的决定性因素是在用 org-download 时,我用的一个配置1

  (use-package org-download
    ...
    :custom  (org-download-screenshot-method "powershell.exe -Command \"(Get-Clipboard -Format image).Save('$(wslpath -w %s)')\""))

因为看到它,我似乎就察觉到一丝玄机,一个特殊的接口就隐藏在这句话中。我想起了一看就知道一件事能成一样,我看到它就知道浙一近给出了一个简单一心德方法,只要稍加修改我就可以用一个小函数(没想到怎么久)让 Org 插图舒适度提升一个档次。

这个启发的确很特别,因为注意到使用 powershell.exe ,我本来想得是直接用文件系统,找到文件夹中最新的

中间一段时间在研究 Windows PowerShell ,主要是看微软把剪切板的相关命令有什么,本来想直接获取截图后剪切板上图片的文字形式(可惜不存在这种形式)然后得到信息。不过最后妥协了,应该是没有。

这里总结一下 ClipBoard 相关命令:2

话说微软这个命令从让人觉得和 Linux 等很不相同,命名似乎生动却繁琐奇怪

GPT 帮忙在于把原来一堆变量合并化简,我同时把名字起得更合适

dir 是所在目录; path 是具体的含文件名的位置

。不过最后还是用了很多变量可是忙活了半天。

我想这还是很笨重的,还依赖于截图会在剪贴板

原来我想可能要找到 Screenshots 文件夹(默认在 C:\Users\JUSTIN\Pictures\Screenshots ,)然后转移到 wsl 中。转移的话, wsl 似乎可以直接访问 \mnt… 然后获取 win 下的文件

不过

对了,我在此顺带用 copilot.el3 把微软 Copliot 接入 Emacs 中, Emacs 这个『上帝』编辑器如今是非常完美了,除了因为简易熟悉我想不到非要使用 VSCode 的理由(哦还有输入法)

想想如果可能我也可以把电脑上给各种便捷配置写写。

Footnotes: